package com.yx.crawler.analyse;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class IdfManager {
	private static String saveFilePath = "./idf/";
	private static String fileName = "idfwords.dat";
	private static String bakFileName = "idfwords.bak";
	private int documentNumber = 0;
	private int doucumentId = -1;

	private HashMap<String, Integer> splitWords = new HashMap<String, Integer>();

	protected IdfManager() {		
		List<String> strList =readFile();
		if(strList==null)strList=readBakFile();
		if(strList==null)return;
		int length=strList.size();
		String [] line=split(strList.get(0));
		documentNumber=Integer.parseInt(line[1]);
		for(int i=1;i<length-1;i++){
			line=split(strList.get(i));
			if(line!=null){
				splitWords.put(line[0], Integer.parseInt(line[1]));
			}
		}
		line=split(strList.get(length-1));
		doucumentId=Integer.parseInt(line[1]);		
	}
	
	private List<String> readFile(){
		List<String> strList =new ArrayList<String>();
		File file = new File(saveFilePath + fileName);
		if (!file.exists())return null;
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new FileReader(file));
			String line = null;
			while ((line = reader.readLine()) != null) {
				strList.add(line);
			}			
		} catch (Exception e) {			
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (Exception e1) {
				}
			}
		}
		int length=strList.size();
		if(length<2||!strList.get(length-1).startsWith("LAST_ID="))return  null;
		String [] line=split(strList.get(0));
		if(line==null||line[0]==null||!line[0].equals("COUNT"))return null;
		return strList;
	}
	private List<String> readBakFile(){
		List<String> strList =new ArrayList<String>();
		File file = new File(saveFilePath + bakFileName);
		if (!file.exists())return null;
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new FileReader(file));
			String line = null;
			while ((line = reader.readLine()) != null) {
				strList.add(line);
			}			
		} catch (Exception e) {			
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (Exception e1) {
				}
			}
		}
		int length=strList.size();
		if(length<2||!strList.get(length-1).startsWith("LAST_ID="))return  null;
		String [] line=split(strList.get(0));
		if(line==null||line[0]==null||!line[0].equals("COUNT"))return null;
		return strList;
	}

	protected synchronized void addDocument(int id, Set<String> keys) {
		documentNumber++;
		doucumentId = id;
		for (String key : keys) {
			if(key==null||"".equals(key))continue;
			if (splitWords.containsKey(key)) {
				splitWords.put(key, splitWords.get(key).intValue() + 1);
			} else {
				splitWords.put(key, 1);
			}
		}
	}

	protected int getLastDoucumentId() {
		return doucumentId;
	}

	protected void addDocument(int id, String content) {
		Set<String> keys = ChineseWordSpliter.getKeywords(content);
		addDocument(id, keys);
	}

	protected synchronized void saveTo() throws Exception {
		FileOutputStream out = null;
		File path = new File(saveFilePath);
		if (!path.exists())path.mkdirs();
		File bakFile=new File(saveFilePath + bakFileName);
		if(bakFile.exists())bakFile.delete();
		File file = new File(saveFilePath + fileName);
		if (file.exists()){
			file.renameTo(bakFile);
		}
		try {
			out = new FileOutputStream(file);
			out.write(("COUNT="+documentNumber + "\r\n").getBytes());
			for (Map.Entry<String, Integer> entry : splitWords.entrySet()) {
				String line = entry.getKey() + "=" + entry.getValue() + "\r\n";
				out.write(line.getBytes());
			}
			out.write(("LAST_ID="+doucumentId + "\r\n").getBytes());
		} finally {
			try {
				out.close();
			} catch (Exception e) {
			}
		}
	}

	protected Double getIdf(String word) {
		double count = 1;
		if (splitWords.containsKey(word)) {
			count = splitWords.get(word).intValue();
		}
		if (documentNumber == 0)
			documentNumber = 1;
		double va = (double) documentNumber / count;
		if (va < 1)
			va = 1;
		double idf = Math.log(va);
		return idf;
	}
	public static String[] split(String line) {
		try {
			String[] lineSplit=new String[2];
			lineSplit[0]=line.substring(0,line.lastIndexOf("="));
			lineSplit[1]=line.substring(line.lastIndexOf("=")+1);			
			return lineSplit;
		} catch (Exception e) {
			return null;
		}
	}
}
